package vip.xiaonuo.biz.modular.lancerCategory.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.modular.pojo.domain.BizCategory;
import vip.xiaonuo.biz.modular.pojo.dto.add.CategoryAddDTO;
import vip.xiaonuo.biz.modular.pojo.dto.common.CommonDeleteDTO;
import vip.xiaonuo.biz.modular.pojo.dto.common.CommonDetailDTO;
import vip.xiaonuo.biz.modular.pojo.dto.edit.CategoryEditDTO;
import vip.xiaonuo.biz.modular.pojo.dto.page.CategoryPageDTO;
import vip.xiaonuo.biz.modular.lancerCategory.service.BizCategoryService;
import vip.xiaonuo.biz.modular.mapper.BizCategoryMapper;
import org.springframework.stereotype.Service;
import vip.xiaonuo.biz.modular.pojo.vo.LV;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author LancerAdmin
 * @description 针对表【biz_category(分类信息)】的数据库操作Service实现
 * @createDate 2024-02-29 14:54:24
 */
@Service
public class BizCategoryServiceImpl extends ServiceImpl<BizCategoryMapper, BizCategory>
        implements BizCategoryService {
    public static final String BIZ_CATEGORY_CACHE_ALL_KEY = "biz-category:all";

    @Resource
    private CommonCacheOperator commonCacheOperator;

    @Override
    public List<BizCategory> getAllCategoryList() {
//        // 从缓存中取
//        Object cacheValue = commonCacheOperator.get(BIZ_CATEGORY_CACHE_ALL_KEY);
//        if(ObjectUtil.isNotEmpty(cacheValue)) {
//            return JSONUtil.toList(JSONUtil.parseArray(cacheValue), BizCategory.class);
//        }
        //        if(ObjectUtil.isNotEmpty(list)) {
//            // 更新到缓存
//            commonCacheOperator.put(BIZ_CATEGORY_CACHE_ALL_KEY, JSONUtil.toJsonStr(list));
//        }
        return this.list(new LambdaQueryWrapper<BizCategory>().orderByAsc(BizCategory::getSort));
    }


    @Override
    public Page<BizCategory> pageLAdmin(CategoryPageDTO dto) {
        LambdaQueryWrapper<BizCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(ObjectUtil.isNotEmpty(dto.getParentId()),
                        BizCategory::getParentId,
                        dto.getParentId())
                .like(ObjectUtil.isNotEmpty(dto.getCategoryName()),
                        BizCategory::getCategoryName,
                        dto.getCategoryName())
                .like(ObjectUtil.isNotEmpty(dto.getCategoryDesc()),
                        BizCategory::getCategoryDesc,
                        dto.getCategoryDesc())
                .orderByDesc(BizCategory::getCreateTime);

        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public BizCategory detail(CommonDetailDTO dto) {
        return this.getById(dto.getId());
    }

    @Override
    public void add(CategoryAddDTO dto) {
        BizCategory obj = BeanUtil.toBean(dto, BizCategory.class);
        // 重复名称
        boolean repeatName = this.count(new LambdaQueryWrapper<BizCategory>().eq(BizCategory::getParentId, obj.getParentId())
                .eq(BizCategory::getCategoryName, obj.getCategoryName())) > 0;
        if(repeatName) {
            throw new CommonException("存在重复的同级分类，名称为：{}", obj.getCategoryName());
        }
        this.save(obj);
    }

    @Override
    @Transactional
    public void delete(List<CommonDeleteDTO> dto) {
        List<String> orgIdList = CollStreamUtil.toList(dto, CommonDeleteDTO::getId);
        if(ObjectUtil.isNotEmpty(orgIdList)) {
            List<BizCategory> allOrgList = this.getAllCategoryList();
            // 获取所有子标签
            List<String> toDeleteOrgIdList = CollectionUtil.newArrayList();
            orgIdList.forEach(orgId -> toDeleteOrgIdList.addAll(this.getChildListById(allOrgList, orgId, true).stream()
                    .map(BizCategory::getId).collect(Collectors.toList())));
            this.removeByIds(toDeleteOrgIdList);
        }
    }
    @Override
    public List<String> getIdListByParentId(String parentId){
        List<BizCategory> originList = this.getAllCategoryList();
        // 获取所有子标签
        List<String> allIdList = CollectionUtil.newArrayList();
        allIdList.addAll(this.getChildListById(originList, parentId, true)
                .stream()
                .map(BizCategory::getId)
                .collect(Collectors.toList()));
        return allIdList;
    }
    public void execRecursionFindChild(List<BizCategory> originDataList, String id, List<BizCategory> resultList) {
        originDataList.forEach(item -> {
            if (item.getParentId().equals(id)) {
                resultList.add(item);
                execRecursionFindChild(originDataList, item.getId(), resultList);
            }
        });
    }

    @Override
    public List<BizCategory> getChildListById(List<BizCategory> originDataList, String id, boolean includeSelf) {
        List<BizCategory> resultList = CollectionUtil.newArrayList();
        execRecursionFindChild(originDataList, id, resultList);
        if (includeSelf) {
            BizCategory self = this.getById(originDataList, id);
            if (ObjectUtil.isNotEmpty(self)) {
                resultList.add(self);
            }
        }
        return resultList;
    }

    @Override
    public BizCategory getById(List<BizCategory> originDataList, String id) {
        int index = CollStreamUtil.toList(originDataList, BizCategory::getId).indexOf(id);
        return index == -1 ? null : originDataList.get(index);
    }

    @Override
    public void edit(CategoryEditDTO dto) {
        BizCategory bizCategory = new BizCategory();
        BeanUtils.copyProperties(dto, bizCategory);
        boolean repeatName = this.count(new LambdaQueryWrapper<BizCategory>().eq(BizCategory::getParentId, bizCategory.getParentId())
                .eq(BizCategory::getCategoryName, bizCategory.getCategoryName())
                .ne(BizCategory::getId, bizCategory.getId())) > 0;
        if (repeatName) {
            throw new CommonException("存在重复的同级标签，名称为：{}", bizCategory.getCategoryName());
        }
        List<BizCategory> originDataList = this.getAllCategoryList();
        boolean errorLevel = this.getChildListById(originDataList, bizCategory.getId(), true).stream()
                .map(BizCategory::getId).collect(Collectors.toList()).contains(bizCategory.getParentId());
        if (errorLevel) {
            throw new CommonException("不可选择上级类别：{}", this.getById(originDataList, bizCategory.getParentId()).getCategoryName());
        }
        this.updateById(bizCategory);
    }

    @Override
    public List<Tree<String>> tree() {
        List<BizCategory> sysOrgList = this.getAllCategoryList();
        List<TreeNode<String>> treeNodeList = sysOrgList.stream().map(x ->
                        new TreeNode<>(x.getId(), x.getParentId(),
                                x.getCategoryName(), x.getCategoryDesc())
                                .setExtra(JSONUtil.parseObj(x)))
                .collect(Collectors.toList());
        return TreeUtil.build(treeNodeList, "0");
    }
    @Override
    public List<Tree<String>> treeClient() {
        return tree();
    }
}




